/**
 *  *2010-6-25 下午08:42:14  add 
 */
package com.base.myproject.client.HR.bcode;

import java.util.List;

import com.base.myproject.client.busi.BaseStore;
import com.base.myproject.client.busi.BaseStoreEvent;
import com.base.myproject.client.busi.BaseStoreListener;
import com.base.myproject.client.busi.BaseTreeStore;
import com.base.myproject.client.busi.ColumnInfo;
import com.base.myproject.client.busi.BO.BusiObject;
import com.base.myproject.client.busi.BO.TreeNodeModelData;
import com.base.myproject.client.jdbc.StoreInfo;
import com.base.myproject.client.system.BaseResource;
import com.base.myproject.client.ui.celleditor.BaseComboBoxX;
import com.base.myproject.client.ui.celleditor.FieldValue;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.Scroll;
import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.Style.VerticalAlignment;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.ModelIconProvider;
import com.extjs.gxt.ui.client.data.ModelStringProvider;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.DateField;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.StoreFilterField;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.form.TriggerField;
import com.extjs.gxt.ui.client.widget.layout.TableData;
import com.extjs.gxt.ui.client.widget.layout.TableLayout;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanelSelectionModel;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel.CheckCascade;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel.CheckNodes;
import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

/**
 * hr的bcode选择对话框，grid，form都可以使用 可对人员进行高级查询 TODO
 * 没有时间处理，未完成，单选，码名映射，能选择公司，未作，最后还要严格测试 zgw 2010-06-26
 * bsd.setSourcecol 是原数据
 * bsd.setTarget_col 是拷贝到目的表的字段 两个必须数组长度一样
 * BcodeSelectDialog bsd = new BcodeSelectDialog();
 * bsd.setTarget_store(getStore()); bsd.setTarget_col(new ColumnInfo[]{new
 * ColumnInfo("createbcode",ColumnInfo.STRING)}); bsd.setSourcecol(new
 * ColumnInfo[]{new ColumnInfo("bcode",ColumnInfo.STRING)});
 * 
 * C9.setEditor(new CellEditor(bsd));
 * 
 * @author Administrator 2010-6-25 javazgw@gmail.com
 */
public class BcodeSelectDialog<D extends ModelData> extends TriggerField<D>
		implements Listener<ComponentEvent>, FieldValue {

	final Window w = new Window();
	// BaseGrid<BusiObject> grid;
	// BaseStore<BusiObject> store;
	StoreInfo info = null;
	Button queryform = new Button("高级");
	Button yesbutton = new Button("查询");
	Button clearbutton = new Button("清除");
	Button okbutton = new Button("确定");
	Button closebutton = new Button("关闭");

	boolean closeon_ok = true;
	FormPanel form = new FormPanel();
	TreePanel<TreeNodeModelData> tree;
	DateTimeFormat activeFormat = DateTimeFormat
			.getFormat("yyyy-MM-dd H:mm:ss");

	protected BaseModelStringProvider<TreeNodeModelData> defaultStringProvider = new BaseModelStringProvider<TreeNodeModelData>();

	ToolBar tb = new ToolBar();
	boolean neesreselect = true; // 弹开对话框不保存上次选择的数据。

	boolean needfilter = false;
	public BcodeSelectDialog() {
		init();
	}

	private void init() {
		queryform.addListener(Events.Select, this);
		yesbutton.addListener(Events.Select, this);
		clearbutton.addListener(Events.Select, this);
		closebutton.addListener(Events.Select, this);
		okbutton.addListener(Events.Select, this);
		initWidget();
		setFireChangeEventOnSetValue(true);
	}

	private void initWidget() {
		w.setHeading("选择");
		w
				.setIcon(AbstractImagePrototype.create(BaseResource.INSTANCE.people()));
		w.setModal(true);
		w.setSize(534, 497);
		w.setMaximizable(true);
		w.setScrollMode(Scroll.AUTO);
		initForm();
		initTreePanel();
		w.add(form);
		w.add(inittoolbar());
		w.add(tree);
	}

	Widget inittoolbar() {
		tb.add(queryform);
		tb.add(yesbutton);
		tb.add(clearbutton);
		tb.add(okbutton);
		tb.add(closebutton);

		return tb;
	}

	/**
	 * 载入数据
	 */
	void load() {
		String sql = "select * from (select a.systembcode,a.bname,a.bcode,a.id,a.sex from systembcode_view a,bcode_job b " +
				"where (a.bcode=b.bcode and b.employstatus='在职') "
				+ "union all select id as systembcode,name,null as bcode,null as id,null as sex from systeminfo"
				+ ") as z  where 1=1";
		// 名字
		if (name.getValue() != null) {
			sql += " and exists (select * from bcode where bcode.bcode=z.bcode and bname like '%"
					+ name.getValue() + "%' )";
		}
		// 省
		if (bc16.getValue() != null && bc16.getValue().get("value") != null) {
			sql += " and exists (select * from bcode where bcode.bcode=z.bcode and hr_Census_Province = '"
					+ bc16.getValue().get("value") + "' )";
		}
		// 市
		if (C_num17.getValue() != null
				&& C_num17.getValue().get("value") != null) {
			sql += " and exists (select * from bcode where bcode.bcode=z.bcode and hr_Census_city = '"
					+ C_num17.getValue().get("value") + "' )";
		}
		// 区
		if (C_num18.getValue() != null
				&& C_num18.getValue().get("value") != null) {
			sql += " and exists (select * from bcode where bcode.bcode=z.bcode and hr_Census_area = '"
					+ C_num18.getValue().get("value") + "' )";
		}
		// 雇佣级别
		if (C_num5.getValue() != null && C_num5.getValue().get("value") != null) {
			sql += "  and exists (select * from bcode_job where employlevel ='"
					+ C_num5.getValue().get("value")
					+ "' and bcode_job.bcode=z.bcode)";
		}
		// 内部职位
		if (C_num6.getValue() != null && C_num6.getValue().get("value") != null) {
			sql += "  and exists (select * from bcode_job where employinnertitle ='"
					+ C_num6.getValue().get("value")
					+ "' and bcode_job.bcode=z.bcode)";
		}
		// 工作类别
		if (C_num20.getValue() != null
				&& C_num20.getValue().get("value") != null) {
			sql += "  and exists (select * from bcode_job where employoutertitle ='"
					+ C_num20.getValue().get("value")
					+ "' and bcode_job.bcode=z.bcode)";
		}

		// 入职日期 从
		if (C_data9.getValue() != null) {
			sql += " and exists (select * from bcode where  hr_entry_date>'"
					+ activeFormat.format(C_data9.getValue()) + "' and bcode.bcode=z.bcode ) ";
		}
		// 入职日期 到
		if (C_data10.getValue() != null) {
			sql += "and exists (select * from bcode where  hr_entry_date<'"
					+ activeFormat.format(C_data10.getValue()) + "' and bcode.bcode=z.bcode ";
		}

		sql += " order by systembcode ";
		hr_salarystore.getStoreinfo().setSql(sql);
		hr_salarystore.getStoreinfo().setForcenolimit("true");
	
		hr_salarystore.load();
	}

	TextField<String> name = new TextField<String>();
	BaseComboBoxX bc16;
	BaseComboBoxX C_num17;
	BaseComboBoxX C_num18;
	BaseComboBoxX C_num5;
	BaseComboBoxX C_num6;
	BaseComboBoxX C_num20;
	DateField C_data9;
	DateField C_data10;

	private void initForm() {

		bc16 = new BaseComboBoxX("name", "dictionary", "where type='hr_p'");
		C_num17 = new BaseComboBoxX("name", "dictionary", "where type='hr_c'");
		C_num18 = new BaseComboBoxX("name", "dictionary", "where type='hr_a'");

		TableLayout tl = new TableLayout();
		tl.setColumns(4);
		form.setLayout(tl);
		TableData td = new TableData();
		td.setRowspan(1);
		td.setHorizontalAlign(HorizontalAlignment.LEFT);
		td.setVerticalAlign(VerticalAlignment.TOP);
		td.setPadding(5);

		form.add(new Label("姓名:"), td);
		form.add(name, td);
		form.add(new Label("户籍省份:"), td);
		form.add(bc16, td);
		form.add(new Label("户籍市:"), td);
		form.add(C_num17, td);
		form.add(new Label("户籍区:"), td);
		form.add(C_num18, td);

		form.add(new Label("雇佣级别:"), td);
		C_num5 = new BaseComboBoxX("name", "dictionary",
				"where type='hr_e_level'");
		form.add(C_num5, td);

		form.add(new Label("内部职位:"), td);
		C_num6 = new BaseComboBoxX("name", "dictionary",
				"where type='hr_title'");
		form.add(C_num6, td);

		form.add(new Label("工作类别:"), td);
		C_num20 = new BaseComboBoxX("name", "dictionary",
				"where type='hr_jobtype'");

		form.add(C_num20, td);

		form.add(new Label("入职日期 从:"), td);
		C_data9 = new DateField();
		form.add(C_data9, td);
		form.add(new Label("到:"), td);
		C_data10 = new DateField();
		form.add(C_data10, td);
		
		form.setAnimCollapse(true);
		form.setCollapsible(true);
		form.setDeferHeight(true);
		form.addListener(Events.Collapse, new Listener() {
			@Override
			public void handleEvent(BaseEvent be) {
				tree.setHeight(400);
			}
		});

		form.addListener(Events.Expand, new Listener() {
			@Override
			public void handleEvent(BaseEvent be) {
				tree.setHeight(200);
			}
		});
		form.setHeaderVisible(false);
		form.setExpanded(false);

	}

	BaseStore<BusiObject> target_store;
	ColumnInfo[] target_col;
	ColumnInfo[] sourcecol;

	/**
	 * 提交后执行
	 * 
	 * @param modeldata
	 */
	public void dopost(final ModelData modeldata) {
		if (sourcecol != null)
			for (int i = 0; i < sourcecol.length; i++) {

				Object o = modeldata.get(sourcecol[i].getName());
				switch (target_col[i].getType()) {
				case ColumnInfo.DOUBLE:
					target_store.setValue(target_col[i].getName(), Double
							.parseDouble(o == null ? "0" : o.toString()));
					break;
				case ColumnInfo.STRING:
					target_store.setValue(target_col[i].getName(), modeldata
							.get(sourcecol[i].getName()));
					break;
				case ColumnInfo.DATETIME:
					target_store.setValue(target_col[i].getName(), modeldata
							.get(sourcecol[i].getName()));
					break;
				default:
					target_store.setValue(target_col[i].getName(), modeldata
							.get(sourcecol[i].getName()));
					break;
				}

				// target_store.setValue(target_col[i],
				// modeldata.get(sourcecol[i]));
			}

		if(isCloseon_ok())
		{
		w.hide();
		}
	}

	/**
	 * 提交后执行,子类继承
	 * 
	 * @param modeldata
	 */
	public void doposted(List<TreeNodeModelData> modeldatalist) {

	}

	/**
	 * 弹出对话框，默认没有选中
	 */
	public void showEditor() {
		GWT.log("checking");
		// 判断是否保持上次选择
		if (isNeesreselect()) {
			deselectall();
		}
		w.show();
	}
	/**
	 * 不选择所有，一般不再外部使用。
	 * 在特殊情况下会有由外部程序控制什么时候清空数据
	 */
	public void deselectall()
	{
		tree.getSelectionModel().deselectAll();
		for (TreeNodeModelData m : tree.getCheckedSelection()) {
			tree.setChecked(m, false);
		}
	}

	BaseTreeStore<TreeNodeModelData> hr_salarystore = null;

	BaseTreeStore<TreeNodeModelData> gethr_salaryStore() {
		if (hr_salarystore == null) {
			createhr_salaryStore();
		}
		return hr_salarystore;
	}

	BaseTreeStore<TreeNodeModelData> createhr_salaryStore() {
		StoreInfo si = new StoreInfo();
		si.setTreesortcolumn("systembcode");
		si.setKeyname(new String[] { "icode" });
		si.setTablename("bcode");

		hr_salarystore = new BaseTreeStore<TreeNodeModelData>(si, false);
		// 用默认的sql载入数据
		load();
		return hr_salarystore;
	}

	void initTreePanel() {
		tree = new TreePanel<TreeNodeModelData>(gethr_salaryStore());
				tree.setDisplayProperty("bname");
		tree.setCheckable(true);
		tree.setAutoLoad(true);
		tree.setHeight(200);
		
		tree.setLabelProvider(defaultStringProvider);
		tree.getStyle().setNodeOpenIcon(
				AbstractImagePrototype.create(BaseResource.INSTANCE
						.tree()));
		tree.getStyle().setNodeCloseIcon(
				AbstractImagePrototype.create(BaseResource.INSTANCE
						.tree()));
		tree.getStyle().setLeafIcon(
				AbstractImagePrototype.create(BaseResource.INSTANCE.bcode()));
		
		setCheckNodes(CheckNodes.BOTH); // 默认只能选择叶子节点
		tree.setCheckStyle(CheckCascade.NONE); //
		TreePanelSelectionModel<TreeNodeModelData> tpsm = new TreePanelSelectionModel<TreeNodeModelData>();
		tpsm.setSelectionMode(SelectionMode.SINGLE);
		tree.setSelectionModel(tpsm);
	}

	/**
	 * 设置选择的类型 CheckNodes.LEAF CheckNodes.PARENT CheckNodes.BOTH
	 * 
	 * @param checkNodes
	 */
	public void setCheckNodes(CheckNodes checkNodes) {
		tree.setCheckNodes(checkNodes);
	}

	@Override
	public void handleEvent(ComponentEvent be) {
		if (be.getSource().equals(yesbutton)) {
			load();
		} else if (be.getSource().equals(clearbutton)) {
			form.reset();
		} else if (be.getSource().equals(closebutton)) {
			w.hide();
		}

		else if (be.getSource().equals(queryform)) {
			form.setExpanded(!form.isExpanded());

		} else if (be.getSource().equals(okbutton)) {
			dopost(tree.getCheckedSelection().get(0));
			doposted(tree.getCheckedSelection());

		}

	}

	/**
	 * 展开
	 */
	public void setExpanded()
	{
		hr_salarystore.addBaseStoreListener(BaseStoreEvent.EventType.LOAD_COMPLETE, new BaseStoreListener(){

			@Override
			public void BaseStoreEventHandle(BaseStoreEvent evt) {
				if(tree.getStore().getModels().size()>0)
					tree.setExpanded(tree.getStore().getModels().get(0), true);
			}

			@Override
			public void onBrowserEvent(Event event) {
			}		
		});	
	}
	public TreeNodeModelData findModel(Object value) {
		// 如果本身就是TreeNodeModelData 那么直接返回。
		GWT.log(value + "");
		if (value instanceof TreeNodeModelData) {
			return (TreeNodeModelData) value;
		}
		TreeNodeModelData val = null;
		if (hr_salarystore.getModels().size() > 0) {
			for (TreeNodeModelData c : hr_salarystore.getAllItems()) {
				if (c.get("value") == null) {
					continue;
				}
				if (c.get("value").equals(value)) {
					val = c;
					break;
				}
			}
		} else {
			val = new TreeNodeModelData();
			val.setNotFlag("value", value);
		}
		return val;
	}

	public void setFilter()
	{
		StoreFilterField<TreeNodeModelData> filter = new StoreFilterField<TreeNodeModelData>() {  
			  
		      @Override  
		      protected boolean doSelect(Store<TreeNodeModelData> store, TreeNodeModelData parent,  
		    		  TreeNodeModelData record, String property, String filter) {  
		    	  if(record==null)
		    		  return false;
		    	  if(!record.isLeaf())
		    	  {
		    		  return false;
		    	  }
		        String bcode = record.get("bcode");  
		        String bname = record.get("bname");  
		       
		        if(bname!=null)
		        if (bname.toLowerCase().startsWith(filter.toLowerCase())) {  
		          return true;  
		        }
		        
		        if(bcode!=null)
			        if (bcode.toLowerCase().startsWith(filter.toLowerCase())) {  
			          return true;  
			        }  
		        
		        return false;  
		      }  
		  
		    };  
		    
		     filter.bind(hr_salarystore);
		     tb.add(filter);
		     if(tb.isRendered())
		     tb.layout();
	}
	/*
	 * public CellEditor getCellEditor() { final CellEditor editor = new
	 * CellEditor(this) {
	 * 
	 * @Override public Object preProcessValue(Object value) { if (value ==
	 * null) { return value; } return findModel(value.toString()); }
	 * 
	 * @Override public Object postProcessValue(Object value) { if (value ==
	 * null) { return value; } // return ((TreeNodeModelData)
	 * value).get("value"); return value; } };
	 * 
	 * this.getOkbutton().addListener(Events.Select, new Listener(){
	 * 
	 * @Override public void handleEvent(BaseEvent be) {
	 * 
	 * editor.postProcessValue(editor.getValue()); GWT.log("ok"); }
	 * 
	 * }); return editor; }
	 */

	@Override
	protected void onTriggerClick(ComponentEvent ce) {
		super.onTriggerClick(ce);
		showEditor();
	}

	@Override
	public Object getCode() {
		return null;
	}

	@Override
	public Object getDisplayname() {
		return null;
	}

	@Override
	public void setCode(Object code) {

	}

	@Override
	public void setDisplayname(Object displayname) {

	}

	public Button getOkbutton() {
		return okbutton;
	}

	public void setOkbutton(Button okbutton) {
		this.okbutton = okbutton;
	}

	public BaseStore<BusiObject> getTarget_store() {
		return target_store;
	}

	public void setTarget_store(BaseStore<BusiObject> targetStore) {
		target_store = targetStore;
	}

	public ColumnInfo[] getTarget_col() {
		return target_col;
	}

	public void setTarget_col(ColumnInfo[] targetCol) {
		target_col = targetCol;
	}

	public ColumnInfo[] getSourcecol() {
		return sourcecol;
	}

	public void setSourcecol(ColumnInfo[] sourcecol) {
		this.sourcecol = sourcecol;
	}

	class BaseModelStringProvider<M extends ModelData> implements
			ModelStringProvider<M> {
		public String getStringValue(M model, String property) {
			Object o = model.get(property);
			if (o == null) {
				return "";
			} else {
				return (model.get("bcode") == null ? "" : model.get("bcode")
						+ ":")
						+ model.get("bname");
			}
		}

	}

	class BaseModelIconProvider<M extends ModelData> implements
			ModelIconProvider<M> {

		@Override
		public AbstractImagePrototype getIcon(M model) {

			if (model.get("sex") != null && model.get("sex").equals("2"))
				return AbstractImagePrototype.create(BaseResource.INSTANCE
						.male16());
			else if (model.get("sex") != null && model.get("sex").equals("1"))
				return AbstractImagePrototype.create(BaseResource.INSTANCE
						.female_16x16());
			else {
				return AbstractImagePrototype.create(BaseResource.INSTANCE
						.organization16());
				
			}
		}

	}

	public TreePanel<TreeNodeModelData> getTree() {
		return tree;
	}

	public void setTree(TreePanel<TreeNodeModelData> tree) {
		this.tree = tree;
	}

	public boolean isNeesreselect() {
		return neesreselect;
	}

	/**
	 * true为不保持上次选择的数据，默认为true，否则保持上一次的选择
	 * 
	 * @param neesreselect
	 */

	public void setNeesreselect(boolean neesreselect) {
		this.neesreselect = neesreselect;
	}

	public boolean isCloseon_ok() {
		return closeon_ok;
	}
	/**
	 * 默认点击确定就关闭对话框，默认是true，否则不关闭
	 * @param closeonOk
	 */

	public void setCloseon_ok(boolean closeonOk) {
		this.closeon_ok = closeonOk;
	}


}
